﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Windows.Documents;

namespace Maze_Generator
{
    class Maze
    {
        private int Width,Height;
        private BitArray MazeArray; // Micro-optimize this like a fucking champ.
        private int[] Start,End,Position;
        private Random Rand = new Random();

        /// <summary>
        /// Creates an empty maze full of walls with the specified width and height.
        /// </summary>
        /// <param name="Width">The width of the maze.</param>
        /// <param name="Height">The height of the maze.</param>
        public Maze(int Width, int Height)
        {
            this.Width = Width;
            this.Height = Height;
            MazeArray = new BitArray(Width * Height);
        }

        /// <summary>
        /// Generates a default array with a random start and stop.
        /// </summary>
        internal void generate()
        {
            Start = new int[2] {Rand.Next(Width-1),0}; // Always at top.
            Position = Start;
            SetCell(Start[0], Start[1], true);
            do
            { // This look prevents start and end being the same column.
                End = new int[2] { Rand.Next(Width-1), Height-1 }; // Always at bottom.
                SetCell(End[0], End[1], true);
            } while (Start == End);
        }

        /// <summary>
        /// Returns the value of the specified cell. Note: Position starts at 0 and ends at width/height -1.
        /// </summary>
        /// <param name="x">The column, starts at 0, ends at 'width-1.'</param>
        /// <param name="y">The row, starts at 0, ends at 'height-1.'</param>
        /// <returns>The value of the specified cell.</returns>
        internal bool GetCell(int x, int y)
        {
            if (x > Width || y > Height)
            {
                throw new InvalidOperationException();
            }
            bool temp = MazeArray[(x * Height) + y];
            return temp; // Desired cell will be x*height places away from origin.
        }

        /// <summary>
        /// Sets the specified cell to the given value. Note: Position starts at 1 and ends at width/height.
        /// </summary>
        /// <param name="x">The column, starts at 1, ends at 'width.'</param>
        /// <param name="y">The row, starts at 1, ends at 'height.'</param>
        /// <param name="value">The value to set.</param>
        internal void SetCell(int x, int y, bool value)
        {
            if (x > 29 || y > 19)
            {
                throw new InvalidOperationException();
            }
            MazeArray[x * Height + y] = value;
        }

        /// <summary>
        /// Returns the current position.
        /// </summary>
        /// <returns>The position.</returns>
        internal int[] GetPosition()
        {
            return Position;
        }

        /// <summary>
        /// Sets the current position to the one given.
        /// </summary>
        /// <param name="Position">A pair tuple containing (x,y).</param>
        internal void SetPosition(int[] Position)
        {
            this.Position = Position;
        }

        /// <summary>
        /// Returns the endpoint of the maze.
        /// </summary>
        /// <returns>The endpoint.</returns>
        internal int[] GetEnd()
        {
            return End;
        }

        /// <summary>
        /// Returns the start location of the maze.
        /// </summary>
        /// <returns>The start location.</returns>
        internal int[] GetStart()
        {
            return Start;
        }
    }
}
